import { Component, OnInit } from '@angular/core'
import { FormBuilder, Validators, FormControl } from '@angular/forms'
import { NzMessageService } from 'ng-zorro-antd'

import { AddMinusService } from '@shared/services/addMinus.service'
import { AcquirerNewBaseClass } from '../baseClass'
import { AcquirerStoreService } from '../acquirer-store.service'
import { User, UserReq } from '@shared/interfaces/user'
import { IFormItem } from '@shared/interfaces/common'
import { MustMatch, makeAllControlDirty } from 'app/utils/helpers'
import { ValidateUserPassword, UsernameConflictAsyncValidator } from 'app/utils/form-control.validator'
import {
  usernameReg,
  nicknameLength,
  emailReg,
  usernameMaxLength,
  usernameMinLength,
  passwordMaxLength,
  passwordMinLength,
  emailMaxLength,
} from 'app/utils/contraints'
import { BusinessService } from '@shared/services/business.service'
import { I18NService } from '@core'

@Component({
  selector: 'app-acquirer-new-user',
  templateUrl: './user.component.html',
  providers: [AddMinusService],
})
export class AcquirerNewUserComponent extends AcquirerNewBaseClass implements OnInit {
  formItems: IFormItem[] = [
    {
      label: this.trans('USER.USERNAME'),
      errTips: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('USER.USERNAME') }),
        maxLength: this.trans('VALIDATION.MAX_LENGTH', { length: usernameMaxLength }),
        minLength: this.trans('VALIDATION.MIN_LENGTH', { length: usernameMinLength }),
        pattern: this.trans('VALIDATION.PATTERN.USERNAME'),
        usernameConflicting: this.trans('VALIDATION.CODE_EXISTS', { name: this.trans('USER.USERNAME') }),
      },
      formControlName: 'username',
    },
    {
      label: this.trans('USER.NAME'),
      errTips: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('USER.NAME') }),
        maxLength: this.trans('VALIDATION.MAX_LENGTH', { length: nicknameLength }),
      },
      formControlName: 'nickName',
    },
    {
      label: this.trans('GENERAL.INFO.EMAIL'),
      errTips: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.INFO.EMAIL') }),
        maxLength: this.trans('VALIDATION.MAX_LENGTH', { length: emailMaxLength }),
        pattern: this.trans('VALIDATION.PATTERN.EMAIL'),
      },
      formControlName: 'email',
    },
    {
      label: this.trans('USER.PASSWORD'),
      errTips: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('USER.PASSWORD') }),
        maxLength: this.trans('VALIDATION.MAX_LENGTH', { length: passwordMaxLength }),
        minLength: this.trans('VALIDATION.MIN_LENGTH', { length: passwordMinLength }),
        passwordInvalid: this.trans('VALIDATION.PATTERN.PASSWORD'),
      },
      inputType: 'password',
      formControlName: 'password',
    },
    {
      label: this.trans('USER.PASSWORD_CONFIRM'),
      errTips: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('USER.PASSWORD_CONFIRM') }),
      },
      errTip: this.trans('USER.VALIDATION.PASSWORD_CONFIRM_NOT_MATCH'),
      inputType: 'password',
      formControlName: 'passwordCF',
    },
  ]

  constructor(
    public fb: FormBuilder,
    public msg: NzMessageService,
    public acquirerStore: AcquirerStoreService,
    public addMinusService: AddMinusService,
    private bizService: BusinessService,
    private i18n: I18NService,
  ) {
    super(fb, acquirerStore)
  }

  ngOnInit() {
    this.initAddMinus()
  }

  initAddMinus(): void {
    const { users } = this.acquirer
    const generateFunc = (user: UserReq) => {
      const { username, nickName, email, password } = user

      return [
        {
          username: new FormControl(username, {
            validators: [
              Validators.required,
              Validators.maxLength(usernameMaxLength),
              Validators.minLength(usernameMinLength),
              Validators.pattern(usernameReg),
            ],
            asyncValidators: [
              UsernameConflictAsyncValidator(this.bizService, this.addMinusService.validateForms, 'username'),
            ],
            updateOn: 'blur',
          }),
          nickName: [nickName, [Validators.required, Validators.maxLength(nicknameLength)]],
          email: [email, [Validators.required, Validators.maxLength(emailMaxLength), Validators.pattern(emailReg)]],
          password: [
            password,
            [
              Validators.required,
              Validators.maxLength(passwordMaxLength),
              Validators.minLength(passwordMinLength),
              ValidateUserPassword,
            ],
          ],
          passwordCF: [password, [Validators.required]],
        },
        {
          validator: MustMatch('password', 'passwordCF'),
        },
      ]
    }
    this.addMinusService.init(generateFunc, new User(), users)
  }

  checkValid(): boolean {
    const valid = this.addMinusService.valid
    if (valid) {
      this.pushDataToStore()
      this.msg.success(this.trans('GENERAL.NOTIFICATION.VALIDATION_SUCCESS'))
    } else {
      this.addMinusService.validateForms.forEach(form => makeAllControlDirty(form))
      this.msg.error(this.trans('GENERAL.NOTIFICATION.VALIDATION_FAIL'))
    }
    return valid
  }

  pushDataToStore(): void {
    this.acquirer.users = this.addMinusService.values
    this.acquirer.users.forEach((user: User) => {
      delete user.passwordCF
    })
    this.acquirerStore.updateValue(this.acquirer)
  }

  minusClickHandler(index: number): void {
    if (this.addMinusService.validateForms.length < 2) {
      this.msg.error(this.trans('USER.NOTIFICATION.AT_LEAST_ONE_USER'))
      return
    }
    this.addMinusService.minusItem(index)
  }

  computeUserTitle(idx: number): string {
    return `${this.trans('USER.TITLE.ITEM')} ${idx + 1}`
  }

  trans(key: string, params?: Object): string {
    return this.i18n.fanyi(key, params)
  }
}
